package de.uni.muenster.idw2.location.bluetooth.service;

import android.util.Log;
import de.uni.muenster.idw2.location.bluetooth.service.fingerprinting.core.DeficientDataException;
import de.uni.muenster.idw2.location.bluetooth.service.transformations.CWPoint;
import de.uni.muenster.idw2.location.bluetooth.service.transformations.GkPoint;
import de.uni.muenster.idw2.location.bluetooth.service.transformations.TransformCoordinates;

/**
 * Base class for the algorithm, the idea is to put here common functionality
 * for position algorithms classes.
 * @author lrodriguez
 *
 */
public class LocationAlgorithm {
	/**
	 * returns the given position-coordinates for a BT-device
	 *
	 * @param name the name of the needed device
	 * @return position of the device in original WGS84-coordinates
	 */
	
	Boolean fullLogModus = false;
	
	public WGS84Position getHostPositionInOriginal(String name){

		double posX=Double.NaN;
		double posY=Double.NaN;
		int posZ= Integer.MIN_VALUE; //NaN not possible because of integer

		for(int index2=0;index2<DataIO.allHosts.size();index2++){
			if(name.equals(DataIO.allHosts.get(index2).bthAdress)){
				posX = DataIO.allHosts.get(index2).bthX;
				posY = DataIO.allHosts.get(index2).bthY;
				posZ = DataIO.allHosts.get(index2).bthFloor;
				break;
				}
			}
		return new WGS84Position(posX, posY, posZ, 0);
	}
	
	/**
	 * returns the coordinates of a BT-device in pixel-coordinates, not in the original WGS84
	 *
	 * @param name hex-name of the BT-adapter 
	 * @return coordinates of device changed to pixel-coordinates
	 */
	public WGS84Position getHostPositionInGK(String name){

		double posX=Double.NaN;
		double posY=Double.NaN;
		int posZ= Integer.MIN_VALUE; //NaN not possible because of integer

		for(int index2=0;index2<DataIO.allHosts.size();index2++){
			if(name.equals(DataIO.allHosts.get(index2).bthAdress)){
				posX = DataIO.allHosts.get(index2).bthX;
				posY = DataIO.allHosts.get(index2).bthY;
				posZ = DataIO.allHosts.get(index2).bthFloor;

				//transform coordinates from WGS84 to GermanGk
				GkPoint tempGkPoint = TransformCoordinates.wgs84ToGermanGk(posY,posX);
				if (fullLogModus) Log.d("AMK", "WGS84 to GermanGK - X:"+posX+" -> "+tempGkPoint.getGkEasting(4900)+" / Y:"+posY+" -> "+tempGkPoint.getNorthing());
				posX = tempGkPoint.getGkEasting(4900);
				posY = tempGkPoint.getNorthing();
				
				break;
				}
			}
		return new WGS84Position(posX, posY, posZ, 0);
	}
	
	/**
	 * Transforms local pixel coordinates to WGS84
	 *
	 * @param point point in local pixel
	 * @return point in WGS84
	 */
	public WGS84Position transformFromGKToWGS84(WGS84Position point)throws DeficientDataException{
		WGS84Position pointWGS84;
		if(point.getLongitude()<3400000 || point.getLongitude()>3500000 || point.getLatitude()<5500000 || point.getLatitude()>6500000){
			if(fullLogModus) Log.d("AMK", "X: "+point.getLongitude()+" / Y: "+point.getLatitude()+" / Z: "+point.getFloor()+" / Acc: "+point.getAccuracy());
			throw new DeficientDataException("Bad result. These coordinates are not exact enough.");
		}
		GkPoint tempGk = new GkPoint(point.getLongitude(),point.getLatitude(), 4900);
		CWPoint tempCW = TransformCoordinates.germanGkToWgs84(tempGk);
		
		
		//TODO set here correct return value
		return new WGS84Position(tempCW.getLonDec(), tempCW.getLatDec(), point.getFloor() ,point.getAccuracy());
	}
}
